#pragma once

#include <map>
#include <vector>

#include "datetime/Timestamp.h"
#include "noncopyable.h"

#include "EventLoop.h"

struct pollfd;

namespace learnmuduo
{
class Channel;

///
/// IO Multiplexing with poll(2).
///
/// This class doesn't own the Channel objects.
class Poller : noncopyable { // 基于 poll(2) 的 I/O 复用器。; Poller 只负责记录 Channel 的关系列表，并在 poll() 返回后找出活跃 Channel。; 注意：Poller 不拥有 Channel，生命周期由上层管理。
public:
  typedef std::vector<Channel*> ChannelList;

  Poller(EventLoop *loop);
  ~Poller();

  /// Polls the I/O events.
  /// Must be called in the loop thread.
  muduo::Timestamp poll(int timeoutMs, ChannelList *activeChannels); // 执行 poll()，返回触发事件的时间。

  /// Changes the interested I/O events.
  /// Must be called in the loop thread.
  void updateChannel(Channel *channel); // 更新 Channel 的感兴趣事件集合。

  void assertInLoopThread() { ownerLoop_->assertInLoopThread(); }

private:
  void fillActiveChannels(int numEvents, ChannelList *activeChannels) const; // 根据 poll 返回的结果填充 activeChannels。

  typedef std::vector<struct pollfd> PollFdList;
  typedef std::map<int, Channel*> ChannelMap;

  EventLoop *ownerLoop_; // 所属的事件循环
  PollFdList pollfds_; // poll 需要的 fd 列表
  ChannelMap channels_; // fd -> Channel*
};
} // namespace learnmuduo
